package org.srtc.infopub.datacenter.storage;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;

import javax.jms.MapMessage;

import org.srtc.infopub.tools.ProtocolPaser;
import org.srtc.infopub.tools.QueryResults;
import org.srtc.infopub.tools.TestXML;

public class TestCache
	{

		public static final int cacheSize = 5;

		private TestXML tXML;

		/**
		 * 所有煤矿信息，用于得到每个矿有多少信息类
		 */
		private TestCoalTable tct;

		/**
		 * 快表信息，用于查看叶子节点
		 */
		private TestQuitTable tqt;

		/**
		 * 所有矿的叶子信息
		 */
		private TestCoalLeavesTable tclt;

		/**
		 * 内存cache
		 */
		public HashMap<String, ArrayList<Object>> cache;

		/**
		 * cache中所有信息项的list
		 */
		public ArrayList<String> allLeaves;

		private static TestCache instance;

		public TestXML gettXML()
			{
				return tXML;
			}

		private TestCache()
			{
				cache = new HashMap<String, ArrayList<Object>>();
				allLeaves = new ArrayList<String>();
			}

		public synchronized static TestCache instance()
			{
				if (instance == null)
					{
						instance = new TestCache();
						instance.initCoalLeavesTable("data_source_define/coalInfo.xml",
								"info_define");
						instance.initCoalsTable("data_source_define/coalInfo.xml");
						instance.createCacheKeys("info_define");
					}
				return instance;
			}

		/**
		 * 初始化煤矿表
		 * 
		 * @param coalXML
		 *            矿配置文件
		 */
		public void initCoalsTable(String coalXML)
			{
				tct = new TestCoalTable(coalXML);
				tct.coalInfos();
			}

		/**
		 * 初始化矿-叶子表
		 * 
		 * @param coalXML
		 * @param dirPath
		 */
		public void initCoalLeavesTable(String coalXML, String dirPath)
			{
				tclt = new TestCoalLeavesTable(coalXML);
				tclt.coalLeaves(dirPath);
			}

		/**
		 * 创建cache中所有信息项的list。以矿名开头，存放所有矿、所有信息类的叶子节点信息
		 */
		public void createCacheKeys(String dirPath)
			{

				tqt = new TestQuitTable();
				tqt.createQuitTable(dirPath);

				Set<Entry<String, ArrayList<String>>> set = tct.getCoals()
						.entrySet();
				Iterator<Entry<String, ArrayList<String>>> it = set.iterator();

				while (it.hasNext())
					{
						Entry<String, ArrayList<String>> en = it.next();
						String coalName = en.getKey();
						ArrayList<String> coalInfo = en.getValue();
						for (int i = 0; i < coalInfo.size(); i++)
							{
								ArrayList<String> arr = getLeavesFromQuitTable(coalInfo
										.get(i) + ".");
								for (int j = 0; j < arr.size(); j++)
									{
										allLeaves.add(coalName + "."
												+ arr.get(j));
									}
							}
					}
			}

		/**
		 * 根据查询节点的名称，找到其所对应的叶子。没有找到返回null
		 * 
		 * @param nodeName
		 * @return
		 */
		public ArrayList<String> getLeavesFromQuitTable(String nodeName)
			{

				HashMap<String, ArrayList<String>> quit = tqt.quitTable;
				ArrayList<String> res = quit.get(nodeName);
				return res;
			}

		/**
		 * 把entry插入cache中
		 * 
		 * @param entry
		 *            格式为：coal.info.item.
		 */
		public void insert(Entry<String, Object> entry)
			{
				String key = entry.getKey();

				if (cache.containsKey(key))
					{
						ArrayList<Object> vls = cache.get(key);
						if (vls.size() == cacheSize)
							{
								vls.remove(cacheSize - 1);
								vls.add(0, entry.getValue());
							} else
							{
								vls.add(0, entry.getValue());
							}
					} else
					{
						ArrayList<Object> vls = new ArrayList<Object>();
						vls.add(entry.getValue());
						cache.put(key, vls);
					}
			}

		public void insert(String str, Object entry)
			{
				String key = str;

				if (cache.containsKey(key))
					{
						ArrayList<Object> vls = cache.get(key);
						if (vls.size() == cacheSize)
							{
								vls.remove(cacheSize - 1);
								vls.add(0, entry);
							} else
							{
								vls.add(0, entry);
							}
					} else
					{
						ArrayList<Object> vls = new ArrayList<Object>();
						vls.add(entry);
						cache.put(key, vls);
					}
			}

		/**
		 * 把hashmap插入到cache中
		 * 
		 * @param coalInfo
		 *            封装好的矿信息
		 */
		public void insertCache(HashMap<String, Object> coalInfo)
			{
				if (coalInfo == null)
					{
						return;
					}

				Set<Entry<String, Object>> s = coalInfo.entrySet();
				Iterator<Entry<String, Object>> it = s.iterator();
				while (it.hasNext())
					{
						Entry<String, Object> entry = it.next();
						insert(entry);
					}
			}

		/**
		 * 把hashmap插入到cache中
		 * 
		 * @param coalInfo
		 *            封装好的矿信息
		 */
		public void insertCache(MapMessage coalInfo)
			{
				if (coalInfo == null)
					{
						return;
					}
				System.out.println("get messages!");

				try
					{
						for (Enumeration enumer = coalInfo.getMapNames(); enumer
								.hasMoreElements();)
							{
								String e = (String) enumer.nextElement();
								String key = e.toString();
								Object value = coalInfo.getObject(key);
								insert(key, value);
							}
					} catch (Exception e)
					{
						e.printStackTrace();
					}
			}

		/**
		 * 经过query解析后（矿+叶子信息）得到的key，根据key查cache得到所对应的value
		 * 
		 * @param key
		 * @return cache中的K，V对
		 */
		public HashMap<String, Object> readCache(String key)
			{
				if (cache == null) {
						return null;
				}
				
				HashMap<String, Object> list = new HashMap<String, Object>();
				if (cache.containsKey(key) && cache.get(key).size() > 0)
					{
						Object v = cache.get(key).get(0);// 只读取第一个元素
						list.put(key, v);
					}

				if (list.isEmpty())
					return null;

				return list;
			}

		/**
		 * 处理query，并完成cache读取
		 * 
		 * @param infoQuery
		 *            请求中的信息类或信息子项,格式：Coal.Info.Item.
		 * @return
		 */
		public HashMap<String, Object> processQuery(ArrayList<String> infoQuery)
			{
				HashMap<String, Object> list = new HashMap<String, Object>();
				ProtocolPaser pp = new ProtocolPaser();

				ArrayList<String> leaf = null;

				for (int i = 0; i < infoQuery.size(); i++)
					{
						String coal = pp
								.getQueryField(infoQuery.get(i), "coal");
						String exCoal = pp.getQueryField(infoQuery.get(i),
								"exceptCoal");
						
						if (coal == null || exCoal == null) {
							return null;
						}

						if (exCoal.equals(""))
							{
								leaf = tclt.getMap().get(coal);
//								System.out.println(leaf + " if");
							} else
							{
								leaf = getLeavesFromQuitTable(exCoal);
//								System.out.println(leaf + "else");
							}
						
						if (leaf == null) {
							return null;
						}

						for (int j = 0; j < leaf.size(); j++)
							{
								HashMap<String, Object> hm = readCache(coal
										+ "." + leaf.get(j));
								if (hm == null) {
									return null;
								}
								 System.out.println(cache);
//								 System.out.println(coal + "." + leaf.get(j));
								appendRes(list, hm);
							}
					}

				return list;
			}

		/**
		 * 合并两个hashmap
		 * 
		 * @param list
		 *            合并后的map
		 * @param hm
		 *            要被合并的map
		 */
		public void appendRes(HashMap<String, Object> list,
				HashMap<String, Object> hm)
			{
				System.out.println(hm);
				Set<Entry<String, Object>> set = hm.entrySet();
				Iterator<Entry<String, Object>> it = set.iterator();

				while (it.hasNext())
					{
						Entry<String, Object> en = it.next();
						list.put(en.getKey(), en.getValue());
					}
			}

		/**
		 * 把返回的hashmap转换成有序的queryresults
		 * 
		 * @param query去掉协议头的请求串
		 *            ，包含矿信息
		 * @param map
		 * @return
		 */
		public QueryResults getQueryResults(ArrayList<String> query, HashMap<String, Object> map) {
			if (map == null) {
				return null;
			}
			
			QueryResults qr = new QueryResults();
			
			for (int i = 0; i<query.size(); i++) {
				Iterator<Entry<String, Object>> it = map.entrySet().iterator();
				while (it.hasNext()) {
					Entry<String, Object> en = it.next();
					if (en.getKey().startsWith(query.get(i))) {
						qr.getArr().add(en);
					}
				}
				Collections.sort(qr.getArr(), new Comparator() {
					
					public int compare(Object en1, Object en2) {
						return ((Entry<String, Object>)en1).getKey().compareTo(((Entry<String, Object>)en2).getKey());
					}
					
				});
			}
			return qr;
		}
		/**
		 * @param args
		 */
		public static void main(String[] args)
			{
				// TODO Auto-generated method stub
				TestCache tc = TestCache.instance();
				tc.initCoalLeavesTable("data_source_define/coalInfo.xml", "info_define");
				tc.initCoalsTable("data_source_define/coalInfo.xml");
				tc.createCacheKeys("info_define");

				HashMap<String, Object> hMap = new HashMap<String, Object>();
				hMap.put("001.001.001.", 1);
				hMap.put("001.001.002.", 2);
				hMap.put("001.001.003.", 3);
				hMap.put("001.001.004.", 4);
				hMap.put("001.001.005.", 5);
				hMap.put("001.001.006.", 6);
				hMap.put("001.001.006.", 7);

				tc.insertCache(hMap);
				//
				// ArrayList<String> ques = new ArrayList<String>();
				// ques.add("PROTOCOL.001.002.002.");
				// ques.add("PROTOCOL.001.001.006.");
				//
				// ArrayList<String> q = new ArrayList<String>();
				// q.add("001.002.002.");
				// q.add("001.001.006.");
				//
				// HashMap<String, Object> m = tc.processQuery(ques);
				// QueryResults qr = tc.getQueryResults(q, m);
				// System.out.println(qr);

				System.out.println(TestCache.instance().cache);
			}

	}
